﻿using System;
using System.Data;
using System.Data.OracleClient;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using ExThreading;
using WPFExcelReport;
using WPFExcelReport.Helpers;
namespace ReflectionStudio.Core.Events
{
    public class EventDispatcher : DispatcherObject
    { 
        #region ----------------SINGLETON----------------
        public static readonly EventDispatcher Instance = new EventDispatcher();
        public bool IsSTA = true;
        /// <summary>
        /// Private constructor for singleton pattern
        /// </summary>
        private EventDispatcher()
        {
            IsSTA = true;
         }
    
        #endregion
        public int _MSGID = 0;
        public int MSGID
        {
            get
            {
                return _MSGID++;
            }
        }
        #region ----------------STATUS BAR----------------
        /// <summary>
        /// Event delegate
        /// </summary>
        public event EventHandler<StatusEventArgs> OnStatusChange;

        /// <summary>
        /// Internal function to raise a status (bar) event
        /// </summary>
        /// <param name="type"></param>
        public void RaiseStatus(string message, StatusEventType type)
        {
            if (!IsSTA)
                return;
            if (CheckAccess())
            {
                StatusEventArgs args = new StatusEventArgs(type, message);

                if (OnStatusChange != null)
                    OnStatusChange(this, args);

                //raise event only if it contains message
                if (message != string.Empty)
                    RaiseMessage(args);
            }
            else
                Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate
                {
                    StatusEventArgs args = new StatusEventArgs(type, message); ;
                    if (OnStatusChange != null)
                        OnStatusChange(this, args);

                    //raise event only if it contains message
                    if (message != string.Empty)
                        RaiseMessage(args);
                });
        }

        #endregion 
        #region ----------------MESSAGE----------------
        /// <summary>
        /// Event delegate
        /// </summary>
        public event EventHandler<MessageEventArgs> OnMessage;

        public void RaiseMessage(MessageInfo info)
        {
            if (!IsSTA)
                return;
            RaiseMessage(new MessageEventArgs(info));
        }


        /// <summary>
        /// Internal function to raise an event
        /// </summary>
        /// <param name="type"></param>
        private void RaiseMessage(MessageEventArgs args)
        {
            if (!IsSTA)
                return;
            Trace.Assert(args != null);

            if (CheckAccess())
            {
                if (OnMessage != null)
                    OnMessage(this, args);
            }
            else
                Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate
                {
                    if (OnMessage != null)
                        OnMessage(this, args);
                });
        }

        private void RaiseMessage(string message)
        {
            if (!IsSTA)
                return;
            Trace.TraceInformation(message);

            if (CheckAccess())
            {
                MessageEventArgs args = new MessageEventArgs(message);

                if (OnMessage != null)
                    OnMessage(this, args);
            }
            else
                Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate
                {
                    MessageEventArgs args = new MessageEventArgs(message);

                    if (OnMessage != null)
                        OnMessage(this, args);
                });
        }

        #endregion 
    }
}
